import MV from '../lib/MV';

class Triangle {
    constructor(angle, numberOfTimesToDivide) {
        // Corners of our gasket with three points.
        this._vertices = [
            MV.vec2(-0.5, -0.5),
            MV.vec2(0,  0.5),
            MV.vec2(0.5, -0.5)
        ];

        this.setDivideNumber(numberOfTimesToDivide || 1);
        this._points = this._originalPoints;

        this.twist(angle);
    }

    getPoints() {
        return this._points;
    }

    setDivideNumber(numberOfTimesToDivide) {
        this._originalPoints = Triangle.divideTriangle(
            this._vertices[0],
            this._vertices[1],
            this._vertices[2],
            numberOfTimesToDivide
        );

        this.twist();
    }

    twist(angleParam) {
        if (angleParam) {
            this._angle = angleParam;
        }

        this._points = this._originalPoints.map(function(point) {
            return Triangle.twistVertex(point, this._angle);
        }.bind(this));
    }

    static divideTriangle(a, b, c, numberOfTimesToDivide) {
        if (numberOfTimesToDivide === 0) {
            return [a, b, c];
        }
        
        //bisect the sides
        let ab = MV.mix(a, b, 0.5);
        let ac = MV.mix(a, c, 0.5);
        let bc = MV.mix(b, c, 0.5);

        // four new triangles
        let t1 = this.divideTriangle(a, ab, ac, numberOfTimesToDivide - 1);
        let t2 = this.divideTriangle(c, ac, bc, numberOfTimesToDivide - 1);
        let t3 = this.divideTriangle(b, bc, ab, numberOfTimesToDivide - 1);
        let t4 = this.divideTriangle(ab, bc, ac, numberOfTimesToDivide - 1);

        return t1.concat(t2).concat(t3).concat(t4);
    }


    static twistVertex(vertex, angleParam) {
        const angle = angleParam || 0;
        const thetaAngle = (Math.PI * angle) / 180;
        let d = this.distanceFromOrigin(vertex);
        let x = vertex[0];
        let y = vertex[1];

        let twistedX = (x * Math.cos(d * thetaAngle)) - (y * Math.sin(d * thetaAngle));
        let twistedY = (x * Math.sin(d * thetaAngle)) + (y * Math.cos(d * thetaAngle));

        return [twistedX, twistedY];
    }

    static distanceFromOrigin(vertex) {
        return Math.sqrt(
            vertex[0] * vertex[0] +
            vertex[1] * vertex[1]
        );
    }
}

module.exports = Triangle;
